package cn.mw.cmdb.entity;

import cn.mw.cmdb.param.ImportContextParam;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.microMonitorCommon.api.user.MwUserApi;
import cn.mw.microMonitorCommon.entity.cmdb.ModelExportDataInfoParam;
import cn.mw.microMonitorCommon.entity.cmdb.MwImportResultParam;
import cn.mw.microMonitorCommon.entity.userDTO.GroupDTO;
import com.alibaba.fastjson.JSONArray;
import com.google.common.base.Strings;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

import static cn.mw.cmdb.entity.PropertyTypeNumerical.isNumeric;
import static cn.mw.cmdb.service.impl.InstanceViewImpl.*;

public class PropertyTypeGroup extends PropertyType<PropertyTypeGroup, Object> {
    public static final String ID = "groups";
    private static List<GroupDTO> finalList = new ArrayList<>();

    private static List<String> finalgroupNameList = new ArrayList<>();


    public PropertyTypeGroup() {
        setId(ID);
        setName("用户组");
        setSortNum(13);
    }

    @Override
    public Object tableHeaderTipInfo(PropertyTypeRef propertyTypeRef) {
        return "多个数据用“,”隔开";
    }

    @Override
    public Criteria doCriteria(CriteriaOpsType opsType, String name, Object value) {
        MwUserApi userApi = PropertyType.userApi;
        List<Long> groupIds = new ArrayList<>();
        if (!isNumeric(value) && !(value instanceof List)) {
            List<GroupDTO> groupsByGroupNames = userApi.getGroupsByGroupNames(Arrays.asList(strValueConvert(value)));
            if (!CollectionUtils.isEmpty(groupsByGroupNames)) {
                for (GroupDTO dto : groupsByGroupNames) {
                    groupIds.add(dto.getId());
                }
            }
            value = groupIds;
        }
        Criteria criteria = null;
        switch (opsType) {
            case is:
            case like:
            case in:
                if (value instanceof List) {
                    criteria = new Criteria(name).in(((List<?>) value).toArray());
                } else {
                    criteria = new Criteria(name).in(value);
                }
                break;
            case nin:
                if (value instanceof List) {
                    criteria = new Criteria(name).nin(((List<?>) value).toArray());
                } else {
                    criteria = new Criteria(name).nin(value);
                }
                break;
            case elemMatch:
                criteria = new Criteria(name).elemMatch(new Criteria().in(JSONArray.parse(strValueConvert(value))));
                break;
            case exist:
                criteria = new Criteria(name).exists((boolean) value);
                break;
            case ne:
                criteria = new Criteria(name).ne(value);
        }
        return criteria;
    }

    @Override
    public Object convertValue(Object value) {
        if (value == null) {
            return null;
        }
        if (!isNumeric(value) && !(value instanceof List)) {
            MwUserApi userApi = PropertyType.userApi;
            List<GroupDTO> groupsByGroupNames = new ArrayList<>();
            List<String> list = Arrays.asList(strValueConvert(value).split(","));
            if (!CollectionUtils.isEmpty(list)) {
                groupsByGroupNames = userApi.getGroupsByGroupNames(new ArrayList<>());
            }
            Map<String, Long> nameByIdMap = groupsByGroupNames.stream().collect(Collectors.toMap(s -> s.getGroupName(), s -> s.getId(), (o1, o2) -> o1));
            List<Long> groupIdList = new ArrayList<>();
            String[] nameArr = strValueConvert(value).split(",");
            if (nameArr != null) {
                for (String name : nameArr) {
                    if (nameByIdMap != null && nameByIdMap.containsKey(name)) {
                        Long groupId = nameByIdMap.get(name);
                        groupIdList.add(groupId);
                    }
                }
            }
            return groupIdList;
        } else {
            return value;
        }
    }


    @Override
    public CriteriaOpsType getDefaultCriteriaOpsType() {
        return CriteriaOpsType.in;
    }

    @Override
    public PropertyTypeGroup newObj() {
        return new PropertyTypeGroup();
    }

    @Override
    public void refresh() {
        finalList.clear();
        finalgroupNameList.clear();
    }

    public boolean tableHeaderInfo(Map ms, PropertyInfo propertyInfo, List<String> labelNames, List<String> labelId) throws Exception {
        //导出表头数据时，表头字段的id和名称不能同时重复
        if ((labelId != null && !labelId.contains(propertyInfo.getId())) && (labelNames != null && !labelNames.contains(ms.get(nameKey)))) {
            ms.put(typeKey, PropertyTypeUser.ID);
            List<String> groupNameList = new ArrayList<>();
            MwUserApi mwUserApi = PropertyType.userApi;
            List<GroupDTO> groupNames = new ArrayList<>();
            if (CollectionUtils.isEmpty(finalgroupNameList)) {
                //调用公共接口，获取对应的信息
                groupNames = mwUserApi.getGroupsByGroupNames(new ArrayList<>());
                if (!CollectionUtils.isEmpty(groupNames)) {
                    for (GroupDTO dto : groupNames) {
                        String name = dto.getGroupName();
                        groupNameList.add(name);
                    }
                    if (!CollectionUtils.isEmpty(groupNameList)) {
                        finalgroupNameList = groupNameList;
                    }
                }
            } else {
                groupNameList = finalgroupNameList;
            }
            labelId.add(propertyInfo.getId());
            ms.put(selectDataKey, groupNameList);
            return true;
        }
        return false;
    }


    @Override
    public Object getDataValue(ImportContextParam contextParam) {
        MwImportResultParam resultParam = new MwImportResultParam();
        List<ModelExportDataInfoParam> list = contextParam.getListInfos();
        ModelExportDataInfoParam importParam = contextParam.getParam();
        if (CollectionUtils.isEmpty(list)) {
            resultParam.setMessage("获取解析失败");
            return resultParam;
        }
        String message = "";
        //属性名称
        String tableName = importParam.getTableName();
        Object cellValue = importParam.getCellValue();
        Map<String, Object> matchMap = new HashMap<>();
        importCheckInfo(resultParam, contextParam, matchMap);
        if (Strings.isNullOrEmpty(strValueConvert(cellValue))) {
            return resultParam;
        }
        MwUserApi mwUserApi = contextParam.getMwUserApi();
        List<GroupDTO> groupsByGroupNames = new ArrayList<>();
        if (CollectionUtils.isEmpty(finalList)) {
            //调用公共接口，获取对应的信息
            groupsByGroupNames = mwUserApi.getGroupsByGroupNames(new ArrayList<>());
            finalList = new ArrayList<>(groupsByGroupNames);
            //根据信息获取用户组Id
        }
        groupsByGroupNames = finalList;
        Map<String, Long> nameByIdMap = groupsByGroupNames.stream().collect(Collectors.toMap(s -> s.getGroupName(), s -> s.getId(), (o1, o2) -> o1));
        List<Long> groupIdList = new ArrayList<>();
        String[] nameArr = strValueConvert(cellValue).split(",");
        if (nameArr != null) {
            for (String name : nameArr) {
                if (nameByIdMap != null && nameByIdMap.containsKey(name)) {
                    Long groupId = nameByIdMap.get(name);
                    groupIdList.add(groupId);
                } else {
                    message += name + "不存在";
                }
            }
        }
        resultParam.setMessage(message);
        resultParam.setCellValue(groupIdList);
        return resultParam;
    }
}
